﻿using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization;

namespace HalconDotNet
{
	/// <summary>Represents a quaternion.</summary>
	// Token: 0x0200005A RID: 90
	[Serializable]
	public class HQuaternion : HData, ISerializable, ICloneable
	{
		/// <summary>Create an uninitialized instance.</summary>
		// Token: 0x06001576 RID: 5494 RVA: 0x0000B2A8 File Offset: 0x000094A8
		public HQuaternion()
		{
		}

		// Token: 0x06001577 RID: 5495 RVA: 0x0000B2B0 File Offset: 0x000094B0
		public HQuaternion(HTuple tuple) : base(tuple)
		{
		}

		// Token: 0x06001578 RID: 5496 RVA: 0x0000B2B9 File Offset: 0x000094B9
		internal HQuaternion(HData data) : base(data)
		{
		}

		// Token: 0x06001579 RID: 5497 RVA: 0x0008AAAC File Offset: 0x00088CAC
		internal static int LoadNew(IntPtr proc, int parIndex, HTupleType type, int err, out HQuaternion obj)
		{
			HTuple t;
			err = HTuple.LoadNew(proc, parIndex, err, out t);
			obj = new HQuaternion(new HData(t));
			return err;
		}

		// Token: 0x0600157A RID: 5498 RVA: 0x0008AAD4 File Offset: 0x00088CD4
		internal static int LoadNew(IntPtr proc, int parIndex, int err, out HQuaternion obj)
		{
			return HQuaternion.LoadNew(proc, parIndex, HTupleType.MIXED, err, out obj);
		}

		// Token: 0x0600157B RID: 5499 RVA: 0x0008AAE0 File Offset: 0x00088CE0
		internal static HQuaternion[] SplitArray(HTuple data)
		{
			int num = data.Length / 4;
			HQuaternion[] array = new HQuaternion[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = new HQuaternion(new HData(data.TupleSelectRange(i * 4, (i + 1) * 4 - 1)));
			}
			return array;
		}

		/// <summary>
		///   Create a rotation quaternion.
		///   Modified instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="axisX">X component of the rotation axis.</param>
		/// <param name="axisY">Y component of the rotation axis.</param>
		/// <param name="axisZ">Z component of the rotation axis.</param>
		/// <param name="angle">Rotation angle in radians.</param>
		// Token: 0x0600157C RID: 5500 RVA: 0x0008AB34 File Offset: 0x00088D34
		public HQuaternion(HTuple axisX, HTuple axisY, HTuple axisZ, HTuple angle)
		{
			IntPtr proc = HalconAPI.PreCall(225);
			HalconAPI.Store(proc, 0, axisX);
			HalconAPI.Store(proc, 1, axisY);
			HalconAPI.Store(proc, 2, axisZ);
			HalconAPI.Store(proc, 3, angle);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			HalconAPI.UnpinTuple(axisX);
			HalconAPI.UnpinTuple(axisY);
			HalconAPI.UnpinTuple(axisZ);
			HalconAPI.UnpinTuple(angle);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
		}

		/// <summary>
		///   Create a rotation quaternion.
		///   Modified instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="axisX">X component of the rotation axis.</param>
		/// <param name="axisY">Y component of the rotation axis.</param>
		/// <param name="axisZ">Z component of the rotation axis.</param>
		/// <param name="angle">Rotation angle in radians.</param>
		// Token: 0x0600157D RID: 5501 RVA: 0x0008ABB4 File Offset: 0x00088DB4
		public HQuaternion(double axisX, double axisY, double axisZ, double angle)
		{
			IntPtr proc = HalconAPI.PreCall(225);
			HalconAPI.StoreD(proc, 0, axisX);
			HalconAPI.StoreD(proc, 1, axisY);
			HalconAPI.StoreD(proc, 2, axisZ);
			HalconAPI.StoreD(proc, 3, angle);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
		}

		// Token: 0x0600157E RID: 5502 RVA: 0x0008AC1C File Offset: 0x00088E1C
		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			HSerializedItem hserializedItem = this.SerializeQuat();
			byte[] value = hserializedItem;
			hserializedItem.Dispose();
			info.AddValue("data", value, typeof(byte[]));
		}

		// Token: 0x0600157F RID: 5503 RVA: 0x0008AC54 File Offset: 0x00088E54
		[EditorBrowsable(EditorBrowsableState.Never)]
		public HQuaternion(SerializationInfo info, StreamingContext context)
		{
			HSerializedItem hserializedItem = new HSerializedItem((byte[])info.GetValue("data", typeof(byte[])));
			this.DeserializeQuat(hserializedItem);
			hserializedItem.Dispose();
		}

		/// <summary>Serialize object to binary stream in HALCON format</summary>
		// Token: 0x06001580 RID: 5504 RVA: 0x0008AC94 File Offset: 0x00088E94
		public void Serialize(Stream stream)
		{
			HSerializedItem hserializedItem = this.SerializeQuat();
			hserializedItem.Serialize(stream);
			hserializedItem.Dispose();
		}

		/// <summary>Deserialize object from binary stream in HALCON format</summary>
		// Token: 0x06001581 RID: 5505 RVA: 0x0008ACA8 File Offset: 0x00088EA8
		public static HQuaternion Deserialize(Stream stream)
		{
			HQuaternion hquaternion = new HQuaternion();
			HSerializedItem hserializedItem = HSerializedItem.Deserialize(stream);
			hquaternion.DeserializeQuat(hserializedItem);
			hserializedItem.Dispose();
			return hquaternion;
		}

		// Token: 0x06001582 RID: 5506 RVA: 0x0008ACCE File Offset: 0x00088ECE
		object ICloneable.Clone()
		{
			return this.Clone();
		}

		// Token: 0x06001583 RID: 5507 RVA: 0x0008ACD8 File Offset: 0x00088ED8
		public HQuaternion Clone()
		{
			HSerializedItem hserializedItem = this.SerializeQuat();
			HQuaternion hquaternion = new HQuaternion();
			hquaternion.DeserializeQuat(hserializedItem);
			hserializedItem.Dispose();
			return hquaternion;
		}

		/// <summary>Composes two quaternions</summary>
		// Token: 0x06001584 RID: 5508 RVA: 0x0008ACFE File Offset: 0x00088EFE
		public static HQuaternion operator *(HQuaternion left, HQuaternion right)
		{
			return left.QuatCompose(right);
		}

		/// <summary>Convert to pose</summary>
		// Token: 0x06001585 RID: 5509 RVA: 0x0008AD07 File Offset: 0x00088F07
		public static implicit operator HPose(HQuaternion quaternion)
		{
			return quaternion.QuatToPose();
		}

		/// <summary>Convert to matrix</summary>
		// Token: 0x06001586 RID: 5510 RVA: 0x0008AD0F File Offset: 0x00088F0F
		public static implicit operator HHomMat3D(HQuaternion quaternion)
		{
			return quaternion.QuatToHomMat3d();
		}

		/// <summary>Conjugate a quaternion</summary>
		// Token: 0x06001587 RID: 5511 RVA: 0x0008AD17 File Offset: 0x00088F17
		public static HQuaternion operator ~(HQuaternion quaternion)
		{
			return quaternion.QuatConjugate();
		}

		/// <summary>
		///   Perform a rotation by a unit quaternion.
		///   Instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="px">X coordinate of the point to be rotated.</param>
		/// <param name="py">Y coordinate of the point to be rotated.</param>
		/// <param name="pz">Z coordinate of the point to be rotated.</param>
		/// <param name="qy">Y coordinate of the rotated point.</param>
		/// <param name="qz">Z coordinate of the rotated point.</param>
		/// <returns>X coordinate of the rotated point.</returns>
		// Token: 0x06001588 RID: 5512 RVA: 0x0008AD20 File Offset: 0x00088F20
		public double QuatRotatePoint3d(double px, double py, double pz, out double qy, out double qz)
		{
			IntPtr proc = HalconAPI.PreCall(222);
			base.Store(proc, 0);
			HalconAPI.StoreD(proc, 1, px);
			HalconAPI.StoreD(proc, 2, py);
			HalconAPI.StoreD(proc, 3, pz);
			HalconAPI.InitOCT(proc, 0);
			HalconAPI.InitOCT(proc, 1);
			HalconAPI.InitOCT(proc, 2);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			double result;
			num = HalconAPI.LoadD(proc, 0, num, out result);
			num = HalconAPI.LoadD(proc, 1, num, out qy);
			num = HalconAPI.LoadD(proc, 2, num, out qz);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Generate the conjugation of a quaternion.
		///   Instance represents: Input quaternion.
		/// </summary>
		/// <returns>Conjugated quaternion.</returns>
		// Token: 0x06001589 RID: 5513 RVA: 0x0008ADAC File Offset: 0x00088FAC
		public HQuaternion QuatConjugate()
		{
			IntPtr proc = HalconAPI.PreCall(223);
			base.Store(proc, 0);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HQuaternion result;
			num = HQuaternion.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Normalize a quaternion.
		///   Instance represents: Input quaternion.
		/// </summary>
		/// <returns>Normalized quaternion.</returns>
		// Token: 0x0600158A RID: 5514 RVA: 0x0008ADFC File Offset: 0x00088FFC
		public HQuaternion QuatNormalize()
		{
			IntPtr proc = HalconAPI.PreCall(224);
			base.Store(proc, 0);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HQuaternion result;
			num = HQuaternion.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Create a rotation quaternion.
		///   Modified instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="axisX">X component of the rotation axis.</param>
		/// <param name="axisY">Y component of the rotation axis.</param>
		/// <param name="axisZ">Z component of the rotation axis.</param>
		/// <param name="angle">Rotation angle in radians.</param>
		// Token: 0x0600158B RID: 5515 RVA: 0x0008AE4C File Offset: 0x0008904C
		public void AxisAngleToQuat(HTuple axisX, HTuple axisY, HTuple axisZ, HTuple angle)
		{
			IntPtr proc = HalconAPI.PreCall(225);
			HalconAPI.Store(proc, 0, axisX);
			HalconAPI.Store(proc, 1, axisY);
			HalconAPI.Store(proc, 2, axisZ);
			HalconAPI.Store(proc, 3, angle);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			HalconAPI.UnpinTuple(axisX);
			HalconAPI.UnpinTuple(axisY);
			HalconAPI.UnpinTuple(axisZ);
			HalconAPI.UnpinTuple(angle);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
		}

		/// <summary>
		///   Create a rotation quaternion.
		///   Modified instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="axisX">X component of the rotation axis.</param>
		/// <param name="axisY">Y component of the rotation axis.</param>
		/// <param name="axisZ">Z component of the rotation axis.</param>
		/// <param name="angle">Rotation angle in radians.</param>
		// Token: 0x0600158C RID: 5516 RVA: 0x0008AEC4 File Offset: 0x000890C4
		public void AxisAngleToQuat(double axisX, double axisY, double axisZ, double angle)
		{
			IntPtr proc = HalconAPI.PreCall(225);
			HalconAPI.StoreD(proc, 0, axisX);
			HalconAPI.StoreD(proc, 1, axisY);
			HalconAPI.StoreD(proc, 2, axisZ);
			HalconAPI.StoreD(proc, 3, angle);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
		}

		/// <summary>
		///   Convert a quaternion into the corresponding 3D pose.
		///   Instance represents: Rotation quaternion.
		/// </summary>
		/// <returns>3D Pose.</returns>
		// Token: 0x0600158D RID: 5517 RVA: 0x0008AF24 File Offset: 0x00089124
		public HPose QuatToPose()
		{
			IntPtr proc = HalconAPI.PreCall(226);
			base.Store(proc, 0);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HPose result;
			num = HPose.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Convert a quaternion into the corresponding rotation matrix.
		///   Instance represents: Rotation quaternion.
		/// </summary>
		/// <returns>Rotation matrix.</returns>
		// Token: 0x0600158E RID: 5518 RVA: 0x0008AF74 File Offset: 0x00089174
		public HHomMat3D QuatToHomMat3d()
		{
			IntPtr proc = HalconAPI.PreCall(229);
			base.Store(proc, 0);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HHomMat3D result;
			num = HHomMat3D.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>Convert the rotational part of a 3D pose to a quaternion.</summary>
		/// <param name="pose">3D Pose.</param>
		/// <returns>Rotation quaternion.</returns>
		// Token: 0x0600158F RID: 5519 RVA: 0x0008AFC4 File Offset: 0x000891C4
		public static HQuaternion[] PoseToQuat(HPose[] pose)
		{
			HTuple htuple = HData.ConcatArray(pose);
			IntPtr proc = HalconAPI.PreCall(230);
			HalconAPI.Store(proc, 0, htuple);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			HalconAPI.UnpinTuple(htuple);
			HTuple data;
			num = HTuple.LoadNew(proc, 0, num, out data);
			HalconAPI.PostCall(proc, num);
			return HQuaternion.SplitArray(data);
		}

		/// <summary>
		///   Convert the rotational part of a 3D pose to a quaternion.
		///   Modified instance represents: Rotation quaternion.
		/// </summary>
		/// <param name="pose">3D Pose.</param>
		// Token: 0x06001590 RID: 5520 RVA: 0x0008B018 File Offset: 0x00089218
		public void PoseToQuat(HPose pose)
		{
			IntPtr proc = HalconAPI.PreCall(230);
			HalconAPI.Store(proc, 0, pose);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			HalconAPI.UnpinTuple(pose);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
		}

		/// <summary>
		///   Interpolation of two quaternions.
		///   Instance represents: Start quaternion.
		/// </summary>
		/// <param name="quaternionEnd">End quaternion.</param>
		/// <param name="interpPos">Interpolation parameter. Default: 0.5</param>
		/// <returns>Interpolated quaternion.</returns>
		// Token: 0x06001591 RID: 5521 RVA: 0x0008B070 File Offset: 0x00089270
		public HQuaternion QuatInterpolate(HQuaternion quaternionEnd, HTuple interpPos)
		{
			IntPtr proc = HalconAPI.PreCall(231);
			base.Store(proc, 0);
			HalconAPI.Store(proc, 1, quaternionEnd);
			HalconAPI.Store(proc, 2, interpPos);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HalconAPI.UnpinTuple(quaternionEnd);
			HalconAPI.UnpinTuple(interpPos);
			HQuaternion result;
			num = HQuaternion.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Multiply two quaternions.
		///   Instance represents: Left quaternion.
		/// </summary>
		/// <param name="quaternionRight">Right quaternion.</param>
		/// <returns>Product of the input quaternions.</returns>
		// Token: 0x06001592 RID: 5522 RVA: 0x0008B0E4 File Offset: 0x000892E4
		public HQuaternion QuatCompose(HQuaternion quaternionRight)
		{
			IntPtr proc = HalconAPI.PreCall(232);
			base.Store(proc, 0);
			HalconAPI.Store(proc, 1, quaternionRight);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HalconAPI.UnpinTuple(quaternionRight);
			HQuaternion result;
			num = HQuaternion.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		/// <summary>
		///   Deserialize a serialized quaternion.
		///   Modified instance represents: Quaternion.
		/// </summary>
		/// <param name="serializedItemHandle">Handle of the serialized item.</param>
		// Token: 0x06001593 RID: 5523 RVA: 0x0008B14C File Offset: 0x0008934C
		public void DeserializeQuat(HSerializedItem serializedItemHandle)
		{
			IntPtr proc = HalconAPI.PreCall(237);
			HalconAPI.Store(proc, 0, serializedItemHandle);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			num = base.Load(proc, 0, num);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			GC.KeepAlive(serializedItemHandle);
		}

		/// <summary>
		///   Serialize a quaternion.
		///   Instance represents: Quaternion.
		/// </summary>
		/// <returns>Handle of the serialized item.</returns>
		// Token: 0x06001594 RID: 5524 RVA: 0x0008B198 File Offset: 0x00089398
		public HSerializedItem SerializeQuat()
		{
			IntPtr proc = HalconAPI.PreCall(238);
			base.Store(proc, 0);
			HalconAPI.InitOCT(proc, 0);
			int num = HalconAPI.CallProcedure(proc);
			base.UnpinTuple();
			HSerializedItem result;
			num = HSerializedItem.LoadNew(proc, 0, num, out result);
			HalconAPI.PostCall(proc, num);
			GC.KeepAlive(this);
			return result;
		}

		// Token: 0x0400112D RID: 4397
		private const int FIXEDSIZE = 4;
	}
}
